package com.yeskery.nut.extend.responsive.convert;

import com.yeskery.nut.core.NutException;
import com.yeskery.nut.extend.responsive.ResponsiveConvert;
import com.yeskery.nut.util.JsonUtils;
import com.yeskery.nut.util.ReflectUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 简单的响应转换接口，不支持嵌套对象，仅仅用于测试，不建议使用
 * @author sprout
 * 2022-06-09 10:40
 */
public class SimpleResponsiveConvert implements ResponsiveConvert {

    /** 日志对象 */
    private static final Logger logger = Logger.getLogger(SimpleResponsiveConvert.class.getName());

    @Override
    public String convertTo(Object data) {
        return JsonUtils.simpleWriteObjectAsString(data);
    }

    @Override
    public Object convertFrom(String data) {
        return JsonUtils.accessMember(data, null, Object.class);
    }

    @Override
    public <T> T convertFromString(String data, Class<T> clazz) {
        Map<String, Object> map = JsonUtils.getMap(data);
        try {
            T instance = clazz.newInstance();
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                try {
                    Field field = clazz.getDeclaredField(entry.getKey());
                    ReflectUtils.setObjectFieldValue(instance, field, entry.getValue());
                } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
                    // Not Deal.
                }
            }
            return instance;
        } catch (Exception e) {
            logger.logp(Level.SEVERE, SimpleResponsiveConvert.class.getName(), "convertFromString",
                    "Execute Fail.", e);
            return null;
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T convertFromStringByType(String data, Type type) {
        if (type instanceof Class) {
            return convertFromString(data, (Class<T>) type);
        }
        throw new NutException("UnSupport Type[" + type.getTypeName() + "].");
    }
}
